/*
 * Copyright (C) <2009>  <Matthew Dickinson>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.pulsarwebdevelopment.concordance;

import java.io.*;
import java.util.*;
import java.util.regex.*;

import android.util.Log;
//import javax.swing.*;

/**
 * Builds concordance from .txt file
 * @author Matthew Dickinson
 * Last updated: 8/22/2009
 */
public class TextProcessor {

	Concordance conc;
	public TextProcessor(int concordance, File baseDir){
		
		conc = new Concordance(concordance, baseDir);
	}
	
	public TextProcessor(String title, String description, File baseDir){
		conc = new Concordance(title, description, baseDir);
	}
	
	/**
	 * Builds a concordance from the given file
	 * @param file
	 * @param concordance
	 * @return Concordance that was generated
	 */
	public Concordance process(File file){
		
		StringBuilder doc = new StringBuilder();
		String document;

		try{
			BufferedReader inFile = new BufferedReader(new FileReader(file));
			String line;
			while((line = inFile.readLine()) != null){
				//StringTokenizer st = new StringTokenizer(line);

				//while(st.hasMoreTokens()){
				doc.append(line + " ");
				//}

			}
		}catch(FileNotFoundException e){
			//TODO display error message
			//JOptionPane.showMessageDialog(null,"File not found");
			System.err.println("File not found: \n"+e.getMessage());
			Log.e("fileProc", "File not found: \n"+e.getMessage());
		}catch(IOException e){
			//TODO display error message
			//JOptionPane.showMessageDialog(null,"File IO exception occurred \n"+ e.getMessage());
			System.err.println("File IO exception occurred : \n"+e.getMessage());
			Log.e("fileProc", "File IO exception occurred: \n"+e.getMessage());
		}catch(Exception e){
			//TODO display error message
			//JOptionPane.showMessageDialog(null, "An error occurred: \n"+e.getMessage());
			System.err.println("An error occurred: \n"+e.getMessage());
			Log.e("fileProc", "An error occurred: \n"+e.getMessage());
		}

		//splitting this statement in two fixes an issue where punctuation that should only be removed if followed by a space would be left because it was followed by other punctuation. (i.e. "He said, 'Bob'."
		document = doc.toString().replaceAll("([\\\"\\.\\?;,!\\(\\)])+", " "); 
		document = document.replaceAll("(: |' | '|--|`)", " ");//there should never be a case where a grave accent shouldn't be removed
		StringTokenizer st = new StringTokenizer(document);
		String word;

		String potentialErrors = "";						//holds possible errors
		Pattern fullRef = Pattern.compile("(\\d)+:(\\d)+");	//Matches 3:16 style references
		Pattern partRef = Pattern.compile("(\\d)+");		//possible verse number
		Pattern bookName = Pattern.compile("\\*(\\w)+\\*");
		Matcher m;
		short chapter = 1;
		short verseNum = 0;									//holds previous verse number
		int bookIndex = 0;
		HashMap<Integer, String> bookNames = new HashMap<Integer, String>();
		Verse verse = new Verse(0,null, (short)0, (short)0); //TEST???

		int position = 0;
		while(st.hasMoreTokens()){
			word = st.nextToken();

			m = partRef.matcher(word);					//checks for verse numbers
			if(m.matches()){
				try{
					short num = Short.parseShort(word);


					if(num > verseNum && num <= (verseNum+2)){

						if(num == (verseNum + 2)){
							potentialErrors += word + " : "+ chapter + ":" + num + "  ";
						}
						verseNum = num;
						verse = new Verse(bookIndex, bookNames.get(bookIndex), chapter, verseNum);
						System.out.println("Verse Number: \t\t  "+word+"   "+num);
						Log.d("fileProc", "Verse Number : "+word+"   "+num);

						//new verse, reset position
						position = 0;

						continue;
					}
				}catch(NumberFormatException e){	
					//verse number is out of range i.e. not a real verse num (except Psalm 119)
					conc.addWord(word, verse);//new Verse(bookIndex, chapter, verseNum));
					System.err.println("number out of bounds");
					Log.e("fileProc", "number out of bouds: \n"+e.getMessage());
					continue;
				}


			}else{
				m = fullRef.matcher(word);
				if(m.matches()){		//Matches 3:16 style references
					//ref = word;

					// reference splitter
					String[] splitRef = word.split(":");
					chapter = Short.parseShort(splitRef[0]);
					verseNum = Short.parseShort(splitRef[1]);
					verse = new Verse(bookIndex, bookNames.get(bookIndex), chapter, verseNum);
					System.out.println("Full Ref:  \t\t\t"+word);
					Log.d("fileProc", "Full Ref:  \t\t\t"+word);

					//new verse, reset position
					position = 0;
					
					continue;
				}else{
					m = bookName.matcher(word);
					if(m.matches()){
						bookIndex = conc.addBook(word.replaceAll("\\*", ""));
						bookNames.put(bookIndex, word.replaceAll("\\*", ""));
						System.out.println("Book name: \t\t  "+word);
						Log.d("fileProc", "Book name: \t\t  "+word);

						//new verse, reset position
						position = 0;
						
						continue;
					}
				}

			}

			//ADD CASE IGNORANCE (MAKE EVERY WORD BE IN CAPITALIZED LOWER CASE)
			String Word = Tools.capitalize(word);
			conc.addWord(Word, verse, ++position);//new Verse(bookIndex, chapter, verseNum));

		}

		return this.conc;	//can be changed to return false if there is an 'terminal' error
	}
}
